import type { PageUrls, RouterConfig } from '@/types/uni-global'
import { deepMerge, qs } from '@/utils'

/**
 * 路由跳转方法，该方法相对于直接使用uni.xxx的好处是使用更加简单快捷
 * 并且带有路由拦截功能
 * 方法来之uview-ui
 */

/**
 * 路由跳转类
 */
class Router {
  private config: RouterConfig

  constructor() {
    this.config = {
      type: 'navigateTo',
      url: '' as PageUrls,
      delta: 1,
      query: {},
      animationType: 'pop-in' as const,
      animationDuration: 300,
      addRootPath: false,
      intercept: false,
    }
    this.route = this.route.bind(this)
  }

  private addRootPath(url: string): string {
    return url[0] === '/' ? url : `/${url}`
  }

  private getCurrentPage(): string {
    const pages = getCurrentPages()
    return pages[pages.length - 1]?.route || ''
  }

  private fail(url?: string): () => void {
    return () => {
      console.error('[Router] navigate fail:', url || '路径不能为空')
    }
  }

  private openPage(config: RouterConfig): void {
    const { url, type, delta, animationType, animationDuration } = config

    switch (type) {
      case 'navigateTo':
      case 'to':
        uni.navigateTo({
          url,
          animationType,
          animationDuration,
          fail: this.fail(url),
        })
        break

      case 'redirectTo':
      case 'redirect':
        uni.redirectTo({
          url,
          fail: this.fail(url),
        })
        break

      case 'switchTab':
      case 'tab':
        uni.switchTab({
          url,
          fail: this.fail(url),
        })
        break

      case 'reLaunch':
      case 'launch':
        uni.reLaunch({
          url,
          fail: this.fail(url),
        })
        break

      case 'navigateBack':
      case 'back':
        uni.navigateBack({
          delta,
          fail: this.fail(),
        })
        break
    }
  }

  async route(options: RouterConfig | string, query: Record<string, any> = {}): Promise<void> {
    let mergeConfig: RouterConfig = { ...this.config }

    if (typeof options === 'string') {
      mergeConfig.url = qs.setQueryString(options, query) as PageUrls
      mergeConfig.type = 'navigateTo'
    } else {
      mergeConfig = deepMerge(mergeConfig, [options]) as RouterConfig
      mergeConfig.url = qs.setQueryString(options.url, { ...query, ...options.query }) as PageUrls
    }

    // 防止重复跳转
    if (mergeConfig.url === this.getCurrentPage()) {
      return
    }

    if (query.intercept) {
      mergeConfig.intercept = query.intercept
    }

    mergeConfig.query = query

    this.openPage(mergeConfig)
    // 路由拦截处理
    // const uni = getApp()
    // if (typeof uni?.$ft?.routeIntercept === 'function') {
    //   const isNext = await new Promise<boolean>((resolve) => {
    //     uni.$ft.routeIntercept(mergeConfig, resolve)
    //   })
    //   if (isNext) {
    //     this.openPage(mergeConfig)
    //   }
    // } else {
    //   this.openPage(mergeConfig)
    // }
  }
}

export default (new Router()).route
